/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package elaborate.vwbe.impl;

import elaborate.h2x.parser.TransformingModelParserBuilder;
import elaborate.h2x.parser.TransformingModelParserBuilderFactory;
import elaborate.h2x.transform.DefaultTransformerImpl;
import elaborate.h2x.transform.Transformer;
import elaborate.h2x.transform.TransformingModel;
import elaborate.vwbe.VWBEApplication;
import elaborate.vwbe.VWBEContext;
import elaborate.vwbe.scripting.ScriptEngine;
import elaborate.vwbe.scripting.ScriptLanguage;
import elaborate.vwbe.scripting.ScriptingException;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 *
 * @author lendle
 */
public class DefaultVWBEApplication implements VWBEApplication{
    private VWBEContext context=null;
    
    public void init(VWBEContext context) {
        this.context=context;
    }

    public Object invokeScriptFunction(ScriptLanguage language, String functionName, Object... args) throws ScriptingException {
        ScriptEngine engine=this.context.getScriptEngine(language);
        if(engine==null){
            throw new ScriptingException("unsupported script language: "+language);
        }
        Object o=engine.invokeFunction(functionName, args);
        return o;
    }
    
    public ScriptEngine getScriptEngine(ScriptLanguage language) throws ScriptingException{
        return this.context.getScriptEngine(language);
    }

    public Iterator<String> getDeclaredScriptFunctions(ScriptLanguage language) {
        try {
            ScriptEngine engine=this.context.getScriptEngine(language);
            if(engine==null){
                throw new ScriptingException("unsupported script language: "+language);
            }
            return engine.getDeclaredScriptFunctions();
        } catch (ScriptingException ex) {
            Logger.getLogger(DefaultVWBEApplication.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public Node applyH2X(Node node) throws Exception {
        TransformingModelParserBuilderFactory tmf=TransformingModelParserBuilderFactory.newInstance();
        TransformingModelParserBuilder tmb=tmf.newTransformingModelParserBuilder();
        Document clonedDocument=(Document) node.getOwnerDocument().cloneNode(false);
        clonedDocument.appendChild(clonedDocument.importNode(node, true));
        TransformingModel model=tmb.newTransformingModelParser().parse(clonedDocument);
        
        Transformer transformer=new DefaultTransformerImpl();
        List<Document> list=transformer.transform(model);
        return list.get(0).getDocumentElement();
    }
}
